package com.kitty.game.attribute;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.kitty.common.utils.SpringUtils;
import com.kitty.game.attribute.config.Attribute;
import com.kitty.game.child.model.ChildInfo;
import com.kitty.game.enter.FiedValue;
import com.kitty.game.enter.TitleInfo;
import com.kitty.game.equip.EquipDataPool;
import com.kitty.game.equip.model.EquipField;
import com.kitty.game.equip.model.RoleEquip;
import com.kitty.game.equip.model.RoleEquipField;
import com.kitty.game.equip.service.EquipService;
import com.kitty.game.fight.service.CountService;
import com.kitty.game.hunpo.service.HunPoService;
import com.kitty.game.hunqiao.HunQiaoService;
import com.kitty.game.hunqiao.model.HunQiaoField;
import com.kitty.game.hunqiao.model.HunQiaoStoreEquipInfo;
import com.kitty.game.hunqiao.model.HunQiaoToSave;
import com.kitty.game.item.config.ChangeCard;
import com.kitty.game.map.service.MapService;
import com.kitty.game.neidan.service.NeidanService;
import com.kitty.game.pet.model.Pet;
import com.kitty.game.pet.service.PetService;
import com.kitty.game.player.model.BossImgInfos;
import com.kitty.game.player.model.HunPoProp;
import com.kitty.game.rank.model.monitor.RoleAttribMonitor;
import com.kitty.game.role.model.Role;
import com.kitty.game.skill.model.RoleSkill;
import com.kitty.game.titleManage.entity.TitleDetailInfo;
import com.kitty.game.titleManage.service.TitleInfoService;
import com.kitty.game.utils.Const;
import com.kitty.game.utils.FormulaUtil;
import com.kitty.game.utils.JsonUtils;
import com.kitty.game.utils.NumberUtil;
import com.kitty.game.wuhun.WuHunPoProp;
import com.kitty.game.wuhun.WuHunService_;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.json.Json;
import org.nutz.lang.Lang;
import org.nutz.lang.util.NutMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;



@Service
@Slf4j
public class AttrService {
    @Autowired
    AttrService attrService;
    @Autowired
    CountService countService;
    @Autowired
    PetService petService;
    @Autowired
    Dao dao;

    @Autowired
    private HunPoService hunPoService;

    @Autowired
    private WuHunService_ WWuHunService;

    @Autowired
    private NeidanService neidanService;

    /**
     * 初始化属性数据
     */
    public void initAttribute() {
        List<Attribute> list = dao.query(Attribute.class, Cnd.NEW());
        Map<Short, Attribute> id2Attribute = new HashMap<>(list.size());
        Map<String, Short> name2AttriId = new HashMap<>(list.size());
        for (Attribute attribute : list) {
            id2Attribute.put(attribute.getAttrId(), attribute);
            name2AttriId.put(attribute.getName().trim(), attribute.getAttrId());
        }
        EquipDataPool.id2Attribute = id2Attribute;
        EquipDataPool.name2AttribId = name2AttriId;
    }


    /**
     * 取属性By Id
     */
    public Attribute getAttr(int id) {
        return EquipDataPool.id2Attribute.get((short) id);
    }


    /**
     * 取属性类型
     */
    public byte getAttrType(int id) {
        return EquipDataPool.id2Attribute.get((short) id).getType();
    }

    /**
     * 取属性By name
     */
    public Attribute getAttrByName(String name) {
        return getAttr(EquipDataPool.name2AttribId.get(name));
    }


    /**
     * 登录后调用增益
     *
     * @return
     */
    public LinkedHashMap<Short, FiedValue> countExtraAttribute(Role role) {
        /**忽略的属性列表*/
        List<Short> ignoreField = Arrays.asList((short) 1, (short) 3330, (short) 3586,
                (short) 3842, (short) 6658, (short) 6146, (short) 6402, (short) 5890,
                (short) 7170, (short) 5378, (short) 5634, (short) 6914);
        EquipService equipService = SpringUtils.getEquipService();

        int size = 0;
        int artifactPolar = 0;
        boolean isEnableSuit = true;
        LinkedHashMap<Short, FiedValue> linkedHashMap = new LinkedHashMap<>();

        for (Byte equipPos : Const.MAIN_PAGE) {
            RoleEquip roleEquip = equipService.getRoleEquipByPos(role, equipPos);
            if (roleEquip == null) {
                continue;
            }
            if (roleEquip.isArtifact()) {
                artifactPolar = roleEquip.queryArtifactPolar();
            }
            if (equipPos == Const.WEAPON || equipPos == Const.HELMET || equipPos == Const.ARMOR || equipPos == Const.BOOT) {
                FiedValue fiedValue = roleEquip.getFields().get((short) 1).getField().get((short) 269);
                if (fiedValue != null) {
                    int enable = getValue(fiedValue.getValue());
                    /**因为是同步修改的 只要有一个不等于激活 那么套装就不生效*/
                    if (enable != 1) {
                        isEnableSuit = false;
                    }
                }
                /**共鸣生效的属性 穿上装备时赋值 卸下删除 所以只有4件的时候才生效*/
                RoleEquipField roleEquipField = roleEquip.getFields().get((short) 7426);
                if (roleEquipField != null) {
                    size++;
                }
            }

            if (equipPos == Const.TALISMAN) {
                roleEquip.getHunQiFields().get((short) 260).getField().forEach(e -> {
                    //有属性
                    if (e.getYangRate() > 0) {
                        {
                            int attrId = EquipDataPool.name2AttribId.getOrDefault(e.getYangAttrName(), (short) 0);
                            FiedValue fiedValue = new FiedValue(attrId, e.getYangAttrVal());
                            addAttribute(linkedHashMap, fiedValue);
                        }

                        {
                            int attrId = EquipDataPool.name2AttribId.getOrDefault(e.getYinAttrName(), (short) 0);
                            FiedValue fiedValue = new FiedValue(attrId, e.getYinAttrVal());
                            addAttribute(linkedHashMap, fiedValue);
                        }
                    }
                });

            }
        }

        {
            RoleSkill roleSkill = role.getSkillBox().querySkillBy(301);
            FiedValue fiedValue = new FiedValue();
            if (roleSkill != null) {
                short skillLevel = roleSkill.getLevel();
                fiedValue.setType((short) 7);
                fiedValue.setVT((byte) 3);
                fiedValue.setValue(new Double(role.getLevel() * 1.5 * skillLevel).intValue());
                addAttribute(linkedHashMap, fiedValue);
            }

            roleSkill = role.getSkillBox().querySkillBy(302);
            fiedValue = new FiedValue();
            if (roleSkill != null) {
                short skillLevel = roleSkill.getLevel();
                fiedValue.setType((short) 12);
                fiedValue.setVT((byte) 3);
                fiedValue.setValue(new Double(role.getLevel() * 1.2 * skillLevel).intValue());
                addAttribute(linkedHashMap, fiedValue);
            }
        }
        //仙魔点
        ChildInfo info = role.getChildInfo();
        if(info != null){
            //重新计算仙道魔道点
            addAttribute(linkedHashMap, new FiedValue(925, info.getXian()));
            addAttribute(linkedHashMap, new FiedValue(926, info.getMo()));
            addAttribute(linkedHashMap, new FiedValue(927, info.getUpgradeTotal()));
        }
        /**坐骑增益*/
        if (role.getMount() >= 1) {
            Pet mount = SpringUtils.getPetService().getPetById(role.getMount(), role);
            if (mount != null) {
                int currTime = new Long(new Date().getTime() / 1000).intValue();
                if (mount.getMountTime() > currTime) {//风灵丸时间大于当前时间才给计算增益属性
                    List<FiedValue> fieldList = petService.getMountAttrib(mount).getFieldValues();
                    for (FiedValue fiedValue : fieldList) {
                        addAttribute(linkedHashMap, fiedValue);
                    }
                }
            }
        }

        for (Byte equipPos : Const.MAIN_PAGE) {
            RoleEquip roleEquip = equipService.getRoleEquipByPos(role, equipPos);
            if (roleEquip == null) {
                if (Const.NECKLACE == equipPos) {//如果正在装备的首饰部位没有装备 去备用位置找
                    roleEquip = equipService.getRoleEquipByPos(role, Const.BACK_NECKLACE);
                    if (roleEquip == null) {
                        continue;
                    }
                } else if (Const.LEFT_WRIST == equipPos) {//如果正在装备的首饰部位没有装备 去备用位置找
                    roleEquip = equipService.getRoleEquipByPos(role, Const.BACK_LEFT_WRIST);
                    if (roleEquip == null) {
                        continue;
                    }
                } else if (Const.RIGHT_WRIST == equipPos) {//如果正在装备的首饰部位没有装备 去备用位置找
                    roleEquip = equipService.getRoleEquipByPos(role, Const.BACK_RIGHT_WRIST);
                    if (roleEquip == null) {
                        continue;
                    }
                } else if (Const.BALDRIC == equipPos) {//如果正在装备的首饰部位没有装备 去备用位置找
                    roleEquip = equipService.getRoleEquipByPos(role, Const.BACK_BALDRIC);
                    if (roleEquip == null) {
                        continue;
                    }
                } else if (Const.ARTIFACT == equipPos) {//如果正在装备的首饰部位没有装备 去备用位置找
                    roleEquip = equipService.getRoleEquipByPos(role, Const.BACK_ARTIFACT);
                    if (roleEquip == null) {
                        continue;
                    }
                } else {
                    continue;
                }
            }
            for (Map.Entry<Short, RoleEquipField> entry : roleEquip.getFields().entrySet()) {
                if (entry.getValue().getField() == null) {
                    continue;
                }
                /**如果是如下忽略的属性位置 不需要添加*/
                if (ignoreField.contains(entry.getKey())) {
                    continue;
                }
                /**判断共鸣属性是否生效*/
                /**共鸣属性要4件一起才生效 取最低改造等级的属性*/
                if (entry.getValue().getType() == 7426) {// 共鸣生效的属性
                    if (size >= 4) {
                        for (FiedValue fieldValue : entry.getValue().getField().values()) {
                            if (fieldValue.getType() == 208) {/**跳过等级字段*/
                                continue;
                            }
                            addAttribute(linkedHashMap, fieldValue);
                        }
                    }
                } else if (entry.getValue().getType() == 2050 || entry.getValue().getType() == 3074) {
                    /**增加套装属性**/
                    if (isEnableSuit) {
                        for (FiedValue fieldValue : entry.getValue().getField().values()) {
                            addAttribute(linkedHashMap, fieldValue);
                        }
                    }
                    /**改造属性的气血和法力需要单独拿出来*2*/
                } else if (entry.getValue().getType() == 2562) {
                    for (FiedValue fieldValue : entry.getValue().getField().values()) {
                        if (fieldValue.getType() == 7 || fieldValue.getType() == 8) {//改造气血 和改造防御
                            FiedValue newField = JsonUtils.cloneObject(fieldValue);
                            int value = getValue(newField.getValue()) * 2;
                            newField.setValue(value);
                            addAttribute(linkedHashMap, newField);
                        } else {
                            addAttribute(linkedHashMap, fieldValue);
                        }

                    }
                } else {
                    for (FiedValue fieldValue : entry.getValue().getField().values()) {
                        addAttribute(linkedHashMap, fieldValue);
                    }
                }
            }
        }

        {
            //魂窍
            HunQiaoToSave hunQiaoToSave =   SpringUtils.getBean(HunQiaoService.class).hunQiaoToSave(role.getRoleId());
            List<HunQiaoStoreEquipInfo> cangKus = hunQiaoToSave.getCangKus();

            for(int itemUnique:hunQiaoToSave.getHunQiao()){
                if(itemUnique!=0){
                    for(HunQiaoStoreEquipInfo hunQiaoStoreEquipInfo:cangKus){
                        List<EquipField> equipFields = hunQiaoStoreEquipInfo.getEquipFields();
                        for(EquipField equipField : equipFields){
                            List<FiedValue> fieldValues = equipField.getFieldValues();

                            for(FiedValue fiedValue :fieldValues){
                                if(fiedValue.getType()==84&&fiedValue.getValue().equals(itemUnique)){
                                    //属性加上去
                                    for(HunQiaoField hunQiaoField:hunQiaoStoreEquipInfo.getHunQiaoFields()){
                                        FiedValue fiedValueToAdd = new FiedValue(hunQiaoField.getId(), hunQiaoField.getVal());
                                        addAttribute(linkedHashMap, fiedValueToAdd);
                                    }
                                }
                            }
                        }

                    }
                }
            }


        }
        return getResult(linkedHashMap, role, artifactPolar);
    }


    /**
     * 添加增益属性
     */
    private void addAttribute(LinkedHashMap<Short, FiedValue> linkedHashMap, FiedValue addField) {
        FiedValue temp = linkedHashMap.get(addField.getType());
        if (temp == null) {
            FiedValue fieldValue = new FiedValue();
            fieldValue.setType(addField.getType());
            fieldValue.setVT(addField.getVT());
            fieldValue.setValue(addField.getValue());
            linkedHashMap.put(fieldValue.getType(), fieldValue);
        } else {
            int tempValue = getValue(temp.getValue());
            int addValue = getValue(addField.getValue());
            temp.setValue(tempValue + addValue);
        }

    }


    /**
     * 计算增益属性结果
     */
    private LinkedHashMap<Short, FiedValue> getResult(LinkedHashMap<Short, FiedValue> filedMap, Role role, int artifactPolar) {
        RoleAttribMonitor roleAttribMonitor = new RoleAttribMonitor(role);

        int allPolar = filedMap.get((short) 221) == null ? 0 : getValue(filedMap.get((short) 221).getValue());//所有相性
        //增加每日累计充值赠送相性活动
        allPolar += role.getExtendBox().getPolorNum();
        //宠物兑换增加属性
        allPolar += role.getExtendBox().getPetAllPolorNum();

        //转生增加相性
        allPolar += role.getExtendBox().getZhuanshengpolor();


        int wood = allPolar + getValue(filedMap.get((short) 46) == null ? 0 : filedMap.get((short) 46).getValue());
        int metal = allPolar + getValue(filedMap.get((short) 45) == null ? 0 : filedMap.get((short) 45).getValue());
        int water = allPolar + getValue(filedMap.get((short) 47) == null ? 0 : filedMap.get((short) 47).getValue());
        int fire = allPolar + getValue(filedMap.get((short) 48) == null ? 0 : filedMap.get((short) 48).getValue());
        int earth = allPolar + getValue(filedMap.get((short) 49) == null ? 0 : filedMap.get((short) 49).getValue());


        metal+= role.getExtendBox().getPolor1();
        wood+= role.getExtendBox().getPolor2();
        water+= role.getExtendBox().getPolor3();
        fire+= role.getExtendBox().getPolor4();
        earth+= role.getExtendBox().getPolor5();


        int allAttribute = filedMap.get((short) 220) == null ? 0 : getValue(filedMap.get((short) 220).getValue());//所有属性

        //宠物兑换增加属性
        allAttribute += role.getExtendBox().getPetAllAttrNum();
        //转生增加属性
        allAttribute += role.getExtendBox().getZhuanshengAttr();

        int con = allAttribute + getValue(filedMap.get((short) 5) == null ? 0 : filedMap.get((short) 5).getValue());
        int str = allAttribute + getValue(filedMap.get((short) 2) == null ? 0 : filedMap.get((short) 2).getValue());
        int dex = allAttribute + getValue(filedMap.get((short) 13) == null ? 0 : filedMap.get((short) 13).getValue());
        int wiz = allAttribute + getValue(filedMap.get((short) 9) == null ? 0 : filedMap.get((short) 9).getValue());
        con+= role.getExtendBox().getAddRoleCon();
        str+=  role.getExtendBox().getAddRoleStr();
        dex += role.getExtendBox().getAddRoleDex();
        wiz += role.getExtendBox().getAddRoleWiz();
        //这里修改为 遍历所有拥有的称号。
        //修改成为 所有称号都加属性
        LinkedHashMap<String, TitleInfo> hashMap = role.getExtendBox().getTitleList();
        try{
            for (Map.Entry<String, TitleInfo> stringTitleInfoEntry : hashMap.entrySet()) {
                String name = stringTitleInfoEntry.getKey();
                if("试道大会".equals(stringTitleInfoEntry.getKey())){
                    name = stringTitleInfoEntry.getValue().getTitle();
                }
                if(TitleInfoService.allMapByGroup.containsKey(name)){
                    TitleDetailInfo titleDetailInfo = TitleInfoService.allMapByGroup.get(name);
                    if(StringUtils.isEmpty(titleDetailInfo.getAttr())){
                        continue;
                    }
                    JSONArray titleJars = JSONObject.parseArray(titleDetailInfo.getAttr());
                    for (Object titleJar : titleJars) {
                        JSONObject jsonObject =(JSONObject)titleJar;
                        String field = jsonObject.getString("field");
                        int num = jsonObject.getIntValue("value");
                        if("所有相性".equals(field)){
                            wood  +=num;
                            metal  +=num;
                            water  +=num;
                            fire  +=num;
                            earth  +=num;
                        }
                        if("所有属性".equals(field)){
                            con +=num;
                            str +=num;
                            dex +=num;
                            wiz +=num;
                        }
                    }
                }
            }
        }catch (Exception e){
            log.info("获取称号加成出错：{}",e);
        }


//
//        /*元旦充值活动属性*/
//        if (role.getExtendBoxJson() != null && role.getExtendBoxJson().contains(Const.TITLE_NAME_YUANDAN_1)) {
//            con = con + 10;
//            str = str + 10;
//            dex = dex + 10;
//            wiz = wiz + 10;
//        }
//        if (role.getExtendBoxJson() != null && role.getExtendBoxJson().contains(Const.TITLE_NAME_YUANDAN_2)) {
//            con = con + 20;
//            str = str + 20;
//            dex = dex + 20;
//            wiz = wiz + 20;
//        }
//        if (role.getExtendBoxJson() != null && role.getExtendBoxJson().contains(Const.TITLE_NAME_YUANDAN_3)) {
//            wood = wood + 10;
//            metal = metal + 10;
//            water = water + 10;
//            fire = fire + 10;
//            earth = earth + 10;
//        }
        //反震度
        int damageSel = getValue(filedMap.get((short) 80) == null ? 0 : filedMap.get((short) 80).getValue());//反震度
        //反震率
        int damageSelRate = getValue(filedMap.get((short) 85) == null ? 0 : filedMap.get((short) 85).getValue());//反震率


        int doubleHit = getValue(filedMap.get((short) 67) == null ? 0 : filedMap.get((short) 67).getValue());//连击
        int doubleHitRate = getValue(filedMap.get((short) 78) == null ? 0 : filedMap.get((short) 78).getValue());//连击率
        int stuntRate = getValue(filedMap.get((short) 79) == null ? 0 : filedMap.get((short) 79).getValue());//必杀率
        int mstuntRate = getValue(filedMap.get((short) 225) == null ? 0 : filedMap.get((short) 225).getValue());//法术必杀率
        int dodge = getValue(filedMap.get((short) 154) == null ? 0 : filedMap.get((short) 154).getValue());//法术躲避
        int penetrateRate = getValue(filedMap.get((short) 117) == null ? 0 : filedMap.get((short) 117).getValue());//破防率
        int penetrate = getValue(filedMap.get((short) 110) == null ? 0 : filedMap.get((short) 110).getValue());//破防

        ///抗性
        int resistAll = getValue(filedMap.get((short) 222) == null ? 0 : filedMap.get((short) 222).getValue());
        int resistMetal = resistAll + getValue(filedMap.get((short) 50) == null ? 0 : filedMap.get((short) 50).getValue());
        int resistWood = resistAll + getValue(filedMap.get((short) 51) == null ? 0 : filedMap.get((short) 51).getValue());
        int resistWater = resistAll + getValue(filedMap.get((short) 52) == null ? 0 : filedMap.get((short) 52).getValue());
        int resistFire = resistAll + getValue(filedMap.get((short) 53) == null ? 0 : filedMap.get((short) 53).getValue());
        int resistEarth = resistAll + getValue(filedMap.get((short) 54) == null ? 0 : filedMap.get((short) 54).getValue());

        //忽视抗性
        int ignoreResistAll = getValue(filedMap.get((short) 168) == null ? 0 : filedMap.get((short) 168).getValue());
        int ignoreResistMetal = ignoreResistAll + getValue(filedMap.get((short) 126) == null ? 0 : filedMap.get((short) 126).getValue());
        int ignoreResistWood = ignoreResistAll + getValue(filedMap.get((short) 127) == null ? 0 : filedMap.get((short) 127).getValue());
        int ignoreResistWater = ignoreResistAll + getValue(filedMap.get((short) 128) == null ? 0 : filedMap.get((short) 128).getValue());
        int ignoreResistFire = ignoreResistAll + getValue(filedMap.get((short) 129) == null ? 0 : filedMap.get((short) 129).getValue());
        int ignoreResistEarth = ignoreResistAll + getValue(filedMap.get((short) 130) == null ? 0 : filedMap.get((short) 130).getValue());

        //抗异常
        int resistAll_ = getValue(filedMap.get((short) 223) == null ? 0 : filedMap.get((short) 223).getValue());
        int resistForgotten = resistAll_ + getValue(filedMap.get((short) 59) == null ? 0 : filedMap.get((short) 59).getValue());
        int resistPoison = resistAll_ + getValue(filedMap.get((short) 56) == null ? 0 : filedMap.get((short) 56).getValue());
        int resistFrozen = resistAll_ + getValue(filedMap.get((short) 57) == null ? 0 : filedMap.get((short) 57).getValue());
        int resistSleep = resistAll_ + getValue(filedMap.get((short) 58) == null ? 0 : filedMap.get((short) 58).getValue());
        int resistConfusion = resistAll_ + getValue(filedMap.get((short) 60) == null ? 0 : filedMap.get((short) 60).getValue());

        //忽视抗异常
        int ignoreResistAll_ = getValue(filedMap.get((short) 169) == null ? 0 : filedMap.get((short) 169).getValue());
        int ignoreResistForgotten = ignoreResistAll_ + getValue(filedMap.get((short) 131) == null ? 0 : filedMap.get((short) 131).getValue());
        int ignoreResistPoison = ignoreResistAll_ + getValue(filedMap.get((short) 132) == null ? 0 : filedMap.get((short) 132).getValue());
        int ignoreResistFrozen = ignoreResistAll_ + getValue(filedMap.get((short) 133) == null ? 0 : filedMap.get((short) 133).getValue());
        int ignoreResistSleep = ignoreResistAll_ + getValue(filedMap.get((short) 134) == null ? 0 : filedMap.get((short) 134).getValue());
        int ignoreResistConfusion = ignoreResistAll_ + getValue(filedMap.get((short) 135) == null ? 0 : filedMap.get((short) 135).getValue());

        //所有技能上升
        short extraSkillLevel = getValue(filedMap.get((short) 224) == null ? 0 : filedMap.get((short) 224).getValue()).shortValue();


        //内丹
        //修复内丹给剩余属性点
//        NeidanProp neidanProp = neidanService.getNeidanProp(role);
//        wood = wood + neidanProp.getTotalPolarPoint();
//        metal = metal + neidanProp.getTotalPolarPoint();
//        water = water + neidanProp.getTotalPolarPoint();
//        fire = fire + neidanProp.getTotalPolarPoint();
//        earth = earth + neidanProp.getTotalPolarPoint();
//
//        con = con + neidanProp.getTotalAttribPoint();
//        str = str + neidanProp.getTotalAttribPoint();
//        dex = dex + neidanProp.getTotalAttribPoint();
//        wiz = wiz + neidanProp.getTotalAttribPoint();
        //内丹结束
        //增益相性
        role.setExtraMetal(metal);
        role.setExtraEarth(earth);
        role.setExtraFire(fire);
        role.setExtraWood(wood);
        role.setExtraWater(water);
        //增益属性
        role.setExtraCon(con);
        role.setExtraDex(dex);
        role.setExtraStr(str);
        role.setExtraWiz(wiz);
        //物伤
        //计算增益属性点和相性点 带来的物理伤害提升
        int extraPhyPower = countService.countExtraPhyPower(role);
        //计算增益属性点和相性点 带来的法术伤害提升
        int extraMagPower =  countService.countExtraMagPower(role);
        //计算增益属性点和相性点 带来的气血提升
        int extraLife = countService.countExtraLife(role);
        //计算增益属性点和相性点 带来的法力提升
        int extraMana = countService.countExtraMana(role);
        //计算增益属性点和相性点 带来的防御提升
        int extraDefense = countService.countExtraDefense(role);
        //计算增益属性点和相性点 带来的速度提升
        int extraSpeed = countService.countExtraSpeed(role);

        //首饰增加的物理伤害
        extraPhyPower += getValue(filedMap.get((short) 808) == null ? 0 : filedMap.get((short) 808).getValue());
        //首饰增加的法术伤害
        extraMagPower += getValue(filedMap.get((short) 808) == null ? 0 : filedMap.get((short) 808).getValue());


        //所有装备物理伤害
        extraPhyPower += getValue(filedMap.get((short) 3) == null ? 0 : filedMap.get((short) 3).getValue());

        //所有装备法术伤害
        extraMagPower += getValue(filedMap.get((short) 10) == null ? 0 : filedMap.get((short) 10).getValue());

        //所有装备气血增加
        extraLife += getValue(filedMap.get((short) 7) == null ? 0 : filedMap.get((short) 7).getValue());

        //所有装备法力增加
        extraMana += getValue(filedMap.get((short) 12) == null ? 0 : filedMap.get((short) 12).getValue());

        //所有装备防御增加
        extraDefense += getValue(filedMap.get((short) 8) == null ? 0 : filedMap.get((short) 8).getValue());

        //所有装备速度增加
        extraSpeed += getValue(filedMap.get((short) 14) == null ? 0 : filedMap.get((short) 14).getValue());

        //悟道 -- 神魂
        int mapId = role.getPos().getMapId();
        MapService mapService = SpringUtils.getBean(MapService.class);
        //if(mapService.queryMapIdType(mapId) == 2){
            HunPoProp hunPoProp = hunPoService.getHunPoProp(role);
            //神魂物伤加成
            extraPhyPower += hunPoProp.getPhyPower();
            //神魂法伤加成
            extraMagPower += hunPoProp.getMagPower();
            //神魂气血加成
            extraLife += hunPoProp.getLife();
            //神魂防御加成
            extraDefense += hunPoProp.getDefense();
            //神魂速度加成
            extraSpeed += hunPoProp.getSpeed();
        //}
        /**武魂加成**/
        WuHunPoProp  WuhunPoProp = WWuHunService.getWuHunPoProp(role);
        //武魂物伤加成
        extraPhyPower += WuhunPoProp.getPhyPower();
        //武魂法伤加成
        extraMagPower += WuhunPoProp.getMagPower();
        //武魂防御加成
        extraDefense += WuhunPoProp.getDefense();
        //武魂速度加成
        extraSpeed += WuhunPoProp.getSpeed();

        //图鉴
        BossImgInfos bossImgInfos = role.getExtendBox().getBossImgInfos();
        if(bossImgInfos == null){
            bossImgInfos = new BossImgInfos();
            role.getExtendBox().setBossImgInfos(bossImgInfos);
        }
        //图鉴物伤加成
        extraPhyPower += role.getExtendBox().getBossImgInfos().getPhyPower();
        //图鉴法伤加成
        extraMagPower += role.getExtendBox().getBossImgInfos().getMagPower();
        //图鉴气血加成
        extraLife += role.getExtendBox().getBossImgInfos().getMaxLife();


        //洛书
        //洛书物伤加成
        extraPhyPower += role.getLuoshumPhypower();
        //洛书法伤加成
        extraMagPower += role.getLuoshuMagpower();
        //洛书防御加成
        extraDefense += role.getLuoshuDefense();
        //洛书速度加成
        extraSpeed +=  role.getLuoshuSpeed();



        //附灵
        int fulinglevel = role.getFulingLevel();
        extraPhyPower +=  11 * fulinglevel;
        //洛书法伤加成
        extraMagPower += 6 * fulinglevel;
        //洛书防御加成
        extraDefense += 22 * fulinglevel;
        //洛书速度加成
        extraSpeed +=  2 * fulinglevel;





        /**把变身卡的属性取出来 由于变身卡属性是百分比增加 所以放到最后面*/
        ChangeCard changeCard = role.getChangeCard();
        if (changeCard != null) {
            Map<Short, Integer> cardFields = new HashMap<>();

            changeCard.getAttrib().forEach(cardAttrib -> {
                short fieldId = getFieldIdByName(cardAttrib.getFieldName());
                cardFields.put(fieldId, cardAttrib.getValue());
            });

            /**取出的属性ID和增益值  有一些是加上去的 有一些是百分比增加*/
            for (Map.Entry<Short, Integer> entry : cardFields.entrySet()) {
                Short fieldId = entry.getKey();
                Integer value = entry.getValue();
                if (fieldId == 50) {
                    resistMetal += value;
                } else if (fieldId == 51) {
                    resistWood += value;
                } else if (fieldId == 52) {
                    resistWater += value;
                } else if (fieldId == 53) {
                    resistFire += value;
                } else if (fieldId == 54) {
                    resistEarth += value;
                } else if (fieldId == 59) {
                    resistForgotten += value;
                } else if (fieldId == 56) {
                    resistPoison += value;
                } else if (fieldId == 57) {
                    resistFrozen += value;
                } else if (fieldId == 58) {
                    resistSleep += value;
                } else if (fieldId == 60) {
                    resistConfusion += value;
                } else if (fieldId == 126) {
                    ignoreResistMetal += value;
                } else if (fieldId == 127) {
                    ignoreResistWood += value;
                } else if (fieldId == 128) {
                    ignoreResistWater += value;
                } else if (fieldId == 129) {
                    ignoreResistFire += value;
                } else if (fieldId == 130) {
                    ignoreResistEarth += value;
                } else if (fieldId == 131) {
                    ignoreResistForgotten += value;
                } else if (fieldId == 132) {
                    ignoreResistPoison += value;
                } else if (fieldId == 133) {
                    ignoreResistFrozen += value;
                } else if (fieldId == 134) {
                    ignoreResistSleep += value;
                } else if (fieldId == 135) {
                    ignoreResistConfusion += value;
                } else if (fieldId == 7) {
                    extraLife += extraLife * (value / 100.0);
                } else if (fieldId == 12) {
                    extraMana += extraMana * (value / 100.0);
                } else if (fieldId == 14) {
                    extraSpeed += extraSpeed * (value / 100.0);
                } else if (fieldId == 8) {
                    extraDefense += extraDefense * (value / 100.0);
                } else if (fieldId == 3) {
                    extraPhyPower += extraPhyPower * (value / 100.0);
                } else if (fieldId == 10) {
                    extraMagPower += extraMagPower * (value / 100.0);
                } else if (fieldId == 225) {
                    mstuntRate += value;
                } else if (fieldId == 79) {
                    stuntRate += value;
                } else if (fieldId == 67) {
                    doubleHit += value;
                } else if (fieldId == 78) {
                    doubleHitRate += value;
                }
            }
        }
        //基础伤害
        int basicPhyPower = countService.countBasicPhyPower(role);
        int basicMana = countService.countBasicMana(role);
        int basicMagPower = countService.countBasicMagPower(role);
        int basicLife = countService.countBasicLife(role);
        int basicDefense = countService.countBasicDefense(role);
        int basicSpeed = countService.countBasicSpeed(role);
        /**法宝增益 飞升后翻倍*/
        if (artifactPolar == Const.SCHOOL_METAL) {  /**金系法宝增加3%法伤*/
            extraMagPower += (int) ((basicMagPower + extraMagPower) * 0.03);
        } else if (artifactPolar == Const.SCHOOL_WOOD) {  /**木系法宝增加5%气血 5%法力*/
            extraLife += (int) ((basicLife + extraLife) * 0.05);
            extraMana += (int) ((basicMana + extraMana) * 0.05);
        } else if (artifactPolar == Const.SCHOOL_WATER) {  /**水系法宝增加6%防御*/
            extraDefense += (int) ((basicDefense + extraDefense) * 0.06);
        } else if (artifactPolar == Const.SCHOOL_FIRE) {  /**火系法宝增加3%速度*/
            extraSpeed += (int) ((basicSpeed + extraSpeed) * 0.03);
        } else if (artifactPolar == Const.SCHOOL_EARTH) {  /**土系法宝增加3%物伤*/
            extraPhyPower += (int) ((basicPhyPower + extraPhyPower) * 0.03);
        }
        role.setExtraPhyPower(extraPhyPower);
        role.setExtraMagPower(extraMagPower);
        role.setExtraMana(extraMana);
        role.setExtraSpeed(extraSpeed);
        role.setExtraDefense(extraDefense);
        role.setExtraLife(extraLife);

        role.setMStuntRate(mstuntRate);//法术必杀
        role.setStuntRate(stuntRate);//必杀
        role.setDoubleHitRate(doubleHitRate);//连击率
        role.setDoubleHit(doubleHit);//连击次数
        role.setDodge(dodge);//法术躲避几率
        role.setPenetrate(penetrate);//破防
        role.setPenetrateRate(penetrateRate);//破防率
        role.setDamageSel(damageSel);
        role.setDamageSelRate(damageSelRate);
        ///抗性
        role.setResistMetal((short) resistMetal);
        role.setResistWood((short) resistWood);
        role.setResistWater((short) resistWater);
        role.setResistFire((short) resistFire);
        role.setResistEarth((short) resistEarth);

        //忽视抗性
        role.setIgnoreResistMetal(ignoreResistMetal);
        role.setIgnoreResistWood(ignoreResistWood);
        role.setIgnoreResistWater(ignoreResistWater);
        role.setIgnoreResistFire(ignoreResistFire);
        role.setIgnoreResistEarth(ignoreResistEarth);

        //抗异常
        role.setResistForgotten((short) resistForgotten);
        role.setResistPoison((short) resistPoison);
        role.setResistFrozen((short) resistFrozen);
        role.setResistSleep((short) resistSleep);
        role.setResistConfusion((short) resistConfusion);

        //忽视抗异常
        role.setIgnoreResistForgotten((short) ignoreResistForgotten);
        role.setIgnoreResistPoison((short) ignoreResistPoison);
        role.setIgnoreResistFrozen((short) ignoreResistFrozen);
        role.setIgnoreResistSleep((short) ignoreResistSleep);
        role.setIgnoreResistConfusion((short) ignoreResistConfusion);

        //所有技能上升
        role.setExtraSkillLevel(extraSkillLevel);
        LinkedHashMap<Short, FiedValue> result = new LinkedHashMap<>();
        ArrayList<FiedValue> fieldValues = new ArrayList<>();
        fieldValues.add(new FiedValue(50, resistMetal));
        fieldValues.add(new FiedValue(51, resistWood));
        fieldValues.add(new FiedValue(52, resistWater));
        fieldValues.add(new FiedValue(53, resistFire));
        fieldValues.add(new FiedValue(54, resistEarth));
        fieldValues.add(new FiedValue(59, resistForgotten));
        fieldValues.add(new FiedValue(56, resistPoison));
        fieldValues.add(new FiedValue(57, resistFrozen));
        fieldValues.add(new FiedValue(58, resistSleep));
        fieldValues.add(new FiedValue(60, resistConfusion));
        fieldValues.add(new FiedValue(126, ignoreResistMetal));
        fieldValues.add(new FiedValue(127, ignoreResistWood));
        fieldValues.add(new FiedValue(128, ignoreResistWater));
        fieldValues.add(new FiedValue(129, ignoreResistFire));
        fieldValues.add(new FiedValue(130, ignoreResistEarth));
        fieldValues.add(new FiedValue(131, ignoreResistForgotten));
        fieldValues.add(new FiedValue(132, ignoreResistPoison));
        fieldValues.add(new FiedValue(133, ignoreResistFrozen));
        fieldValues.add(new FiedValue(134, ignoreResistSleep));
        fieldValues.add(new FiedValue(136, ignoreResistConfusion));
        fieldValues.add(new FiedValue(2, str));
        fieldValues.add(new FiedValue(5, con));
        fieldValues.add(new FiedValue(9, wiz));
        fieldValues.add(new FiedValue(13, dex));
        fieldValues.add(new FiedValue(45, metal));
        fieldValues.add(new FiedValue(46, wood));
        fieldValues.add(new FiedValue(47, water));
        fieldValues.add(new FiedValue(48, fire));
        fieldValues.add(new FiedValue(49, earth));
        fieldValues.add(new FiedValue(7, extraLife));
        fieldValues.add(new FiedValue(12, extraMana));
        fieldValues.add(new FiedValue(14, extraSpeed));
        fieldValues.add(new FiedValue(8, extraDefense));
        fieldValues.add(new FiedValue(3, extraPhyPower));
        fieldValues.add(new FiedValue(10, extraMagPower));
        roleAttribMonitor.end();
        fieldValues.forEach(fieldValue -> result.put(fieldValue.getType(), fieldValue));

//        logger.error("总属性:气血[{}],法力[{}],物攻[{}],法攻[{}],速度[{}],防御[{}]",
//                role.getMaxLife(),role.getMaxMana(),role.getMaxPhyPower(),role.getMaxMagPower(),role.getMaxSpeed(),role.getMaxDefense());
        return result;
    }

    /**
     * 根据属性名取出属性ID
     */
    public short getFieldIdByName(String fieldName) {
        return getAttrByName(fieldName).getAttrId();
    }


    public Integer getValue(Object value) {
        return NumberUtil.intValue(value);
    }

    /**
     * 加载属性数据
     */
    public void loadCommonSet(Map<String, String> commonSetMap) {
        log.error("加载属性配置...");
        AttributeDataPool.fieldMaxMap = Json.fromJson(NutMap.class, commonSetMap.get("field_max"));
        AttributeDataPool.suitFieldMaxMap = Json.fromJson(NutMap.class, commonSetMap.get("suit_field_max"));
        AttributeDataPool.fieldMinMap = Json.fromJson(NutMap.class, commonSetMap.get("field_min"));
        AttributeDataPool.suitFieldMinMap = Json.fromJson(NutMap.class, commonSetMap.get("suit_field_min"));
        AttributeDataPool.nameToName = Json.fromJsonAsMap(String.class, commonSetMap.get("field_name_name"));
        AttributeDataPool.nameToFieldId = Json.fromJsonAsMap(String.class, commonSetMap.get("name_to_fieldId"));
        AttributeDataPool.specialFiledMap = Json.fromJson(NutMap.class, commonSetMap.get("special_fields"));
        AttributeDataPool.basicAttrib = Json.fromJson(NutMap.class, commonSetMap.get("equip_basic_attrib"));
        AttributeDataPool.percentFiledNames = Json.fromJson(Set.class, commonSetMap.get("percent_fieldNames"));
    }


    /**
     * 根据装备部位等级取基础属性
     */
    public NutMap getBasicAttrib(int pos, int level) {
        List<Integer> equipPos = Arrays.asList(1, 2, 3, 10);
        List<Integer> jewelryPos = Arrays.asList(4, 5, 6);
        /**如果是装备才需要取整*/
        if (equipPos.contains(pos) && level != 1) {
            level = (int) (Math.floor(level / 10) * 10);
        } else if (jewelryPos.contains(pos)) {
            level = (int) (Math.floor(level / 5) * 5);
        }
        NutMap map1 = AttributeDataPool.basicAttrib.getAs(String.valueOf(pos), NutMap.class);
        if (map1 != null) {
            return map1.getAs(String.valueOf(level), NutMap.class);
        }
        return new NutMap();
    }

    /**
     * 判断属性是不是特殊属性
     */
    public boolean isSpecialField(int fieldId) {
        String name = getFiledName(fieldId);
        return isSpecialField(name);
    }

    /**
     * 取特殊属性最大值
     */
    public int getSpecialFieldMaxValue(int fieldId) {
        String name = getFiledName(fieldId);
        return getSpecialFieldValue(name, true);
    }

    /**
     * 取特殊属性最小值
     */
    public int getSpecialFieldMinValue(int fieldId) {
        String name = getFiledName(fieldId);
        return getSpecialFieldValue(name, false);
    }

    /**
     * 取属性最大值 属性id 等级 装备部位
     */
    public int getFiledMin(int fieldId, int level, int pos) {
        String name = getFiledName(fieldId);
        try {
            if (isSpecialField(name)) {
                return getSpecialFieldMinValue(fieldId);
            }
            return getFiledValue(name, level, pos, false);
        } catch (Exception e) {
            log.error("属性取值错误 属性ID={},错误信息={}", fieldId, Lang.getStackTrace(e));
            return FormulaUtil.getAttribMinValueByName(level, pos, name);
        }
    }

    /**
     * 取属性最大值 属性id 等级 装备部位
     */
    public int getFiledMax(int fieldId, int level, int pos) {
        String name = getFiledName(fieldId);
        try {
            if (isSpecialField(name)) {
                return getSpecialFieldMaxValue(fieldId);
            }
            return getFiledValue(name, level, pos, true);
        } catch (Exception e) {
            int maxValue = FormulaUtil.getAttribMaxValueByName(level, pos, name);
            log.error("属性取值错误 属性ID={},公式取值={}", fieldId, maxValue);
            return maxValue;
        }

    }

    /**
     * 取属性最大值 属性id 等级 装备部位
     */
    public int getSuitFiledMin(int fieldId, int level, int pos) {
        try {
            String name = getFiledName(fieldId);
            if (isSpecialField(name)) {
                return getSpecialFieldMinValue(fieldId);
            }
            return getSuitFiledValue(name, level, pos, false);
        } catch (Exception e) {
            log.error("属性取值错误 属性ID={},错误信息={}", fieldId, Lang.getStackTrace(e));
            return 0;
        }

    }

    /**
     * 取属性最大值 属性id 等级 装备部位
     */
    public int getSuitFiledMax(int fieldId, int level, int pos) {
        try {
            String name = getFiledName(fieldId);
            if (isSpecialField(name)) {
                return getSpecialFieldMaxValue(fieldId);
            }
            return getSuitFiledValue(name, level, pos, true);
        } catch (Exception e) {
            log.error("属性取值错误 属性ID={},错误信息={}", fieldId, Lang.getStackTrace(e));
            return 0;
        }

    }

    /**
     * 取特殊属性
     */
    public int getSpecialFieldValue(String name, boolean isMax) {
        NutMap map = AttributeDataPool.specialFiledMap.getAs(name, NutMap.class);
        if (isMax) {
            return map.getInt("max");
        } else {
            return map.getInt("min");
        }
    }

    /**
     * 判断属性是不是特殊属性
     */
    public boolean isSpecialField(String name) {
        return !Objects.isNull(AttributeDataPool.specialFiledMap.getAs(name, NutMap.class));
    }

    /**
     * 取属性值 属性英文名 等级 装备部位 取最大还是取最小
     */
    public int getFiledValue(String name, int level, int pos, boolean isMax) {
        NutMap map;
        if (isMax) {
            map = AttributeDataPool.fieldMaxMap.getAs(name, NutMap.class);
        } else {
            map = AttributeDataPool.fieldMinMap.getAs(name, NutMap.class);
        }
        return getFieldValue(level, pos, map);
    }

    /**
     * 取套装属性值 属性英文名 等级 装备部位 取最大还是取最小
     */
    public int getSuitFiledValue(String name, int level, int pos, boolean isMax) {
        NutMap map;
        if (isMax) {
            map = AttributeDataPool.suitFieldMaxMap.getAs(name, NutMap.class);
        } else {
            map = AttributeDataPool.suitFieldMinMap.getAs(name, NutMap.class);
        }
        return getFieldValue(level, pos, map);
    }

    private int getFieldValue(int level, int pos, NutMap map) {
        List<Integer> fields = map.getAsList(String.valueOf(pos), Integer.class);
        return fields.get(level - 1);
    }

    /**
     * 属性名取属性ID
     */
    public int getFiledIdBy(String name) {
        int fieldId = 0;
        for (Map.Entry<String, String> entry : AttributeDataPool.nameToFieldId.entrySet()) {
            String key = entry.getKey();//属性ID
            String value = entry.getValue();//属性名
            if (name.equals(value)) {
                fieldId = Integer.parseInt(key);
                break;
            }
        }
        return fieldId;
    }

    /**
     * 属性ID取属性名
     */
    private String getFiledName(int fieldId) {
        return AttributeDataPool.nameToFieldId.get(String.valueOf(fieldId));
    }

    /**
     * 是否属性值按百分比显示的属性名
     */
    public boolean isPercentFieldName(String fieldName) {
        return AttributeDataPool.percentFiledNames.contains(fieldName);
    }


}
